package com.travel.common.util;

import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @Author: LiZhenhui
 * @Date: 2018/10/31 14:23
 * @Desc:
 */
@Slf4j
public class DateUtil {

    public final static SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");
    public final static SimpleDateFormat YYYYMMDD = new SimpleDateFormat("yyyyMMdd");
    public final static SimpleDateFormat YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static Date strToDate(String str, SimpleDateFormat sdf){
        try {
            return sdf.parse(str);
        }catch (Exception e){
            throw new WorkException(WorkCode.INVALID_PARAM);
        }
    }

    public static String dateToStr(Date date, SimpleDateFormat sdf){
        try {
            return sdf.format(date);
        }catch (Exception e){
            throw new WorkException(WorkCode.INVALID_PARAM);
        }
    }

    public static Date getDateNum(Date date, Integer num){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, num);
        return calendar.getTime();
    }

    public static Date getDataTime(String str){
        try {
            Date time = YYYY_MM_DD.parse(str);
            return get(time, 0, 0, 0, 0);
        }catch (Exception e) {
            log.error("转换时间格式异常：", e);
            throw new WorkException(WorkCode.INVALID_PARAM);
        }
    }

    public static Date getDataEndTime(String str){
        try {
            Date time = YYYY_MM_DD.parse(str);
            return get(time, 23, 59, 59, 999);
        }catch (Exception e) {
            log.error("转换时间格式异常：", e);
            throw new WorkException(WorkCode.INVALID_PARAM);
        }
    }

    public static Date getMonthFirstDay(int index){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, index);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return setDayStart(calendar);
    }


    public static Date getMonthLastDay(int index){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, index);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        return setDayStart(calendar);
    }

    public static Date setDayStart(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return setDayStart(calendar);
    }

    public static Date setDayStart(Calendar calendar){
        return get(calendar.getTime(), 0, 0, 0, 0);
    }

    public static Date setDayEnd(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return setDayEnd(calendar);
    }

    public static Date setDayEnd(Calendar calendar){
        return get(calendar.getTime(), 23, 59, 59, 999);
    }

    public static Date get(Date date, int hour, int minute, int second, int millisecond){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, millisecond);
        return calendar.getTime();
    }

    public static boolean isSameDay(Date date1, Date date2) {
        if(date1 != null && date2 != null) {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameDay(cal1, cal2);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }

    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if(cal1 != null && cal2 != null) {
            return cal1.get(0) == cal2.get(0) && cal1.get(1) == cal2.get(1) && cal1.get(6) == cal2.get(6);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }


    public static Date getIndexDay(Date date, int field, int index){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, index);
        return calendar.getTime();
    }

    public static Date getYearStart(Integer year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }

    public static Date getYearEnd(Integer year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }

    public static int getWeekNum(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);

        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    public static int getYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }
}
